import type { ECharts, EChartsTypes } from '../../../../../types/interfaces'
import type { DiscussionAnalytics } from '../index'
import type {
  DiscussionAnalyticsData,
  DiscussionTimeDistribution,
  DiscussionUserRoleFilter,
} from '../types'
import { BarChart } from '../../../../../components/bar_chart'
import { LineChart } from '../../../../../components/line_chart'
import { Select } from '../../../../../components/select'
import { ClickOutsideHandler } from '../../../../../lib/click_outside_handler'
import { PageHandler } from '../../../../../lib/page_handler'
import { ToolKit } from '../../../../../lib/utils/toolkit'
import { logger, WEEKDAYS_CHINESE } from '../../../../../types/constants'
import { SYMBOLS } from '../../../../../types/interfaces'
import {
  DiscussionUserRole,
  DiscussionUserRoleBadge,
} from '../types'
import { DISCUSSION_SCORE_WEIGHT_CONFIG } from './score/types'

export class DiscussionAnalyticsUI {
  // @Decorators.Identity
  readonly name: string = 'DiscussionAnalyticsUI'
  // @Decorators.PublicState
  private static instance: DiscussionAnalyticsUI
  // @Decorators.Dependency
  private readonly pageHandler: PageHandler = PageHandler.getInstance()
  selectInstance: Select | null = null
  // @Decorators.UIElement
  clickOutsideHandler: ClickOutsideHandler | null = null
  readonly DASHBOARD_ID: string = 'discussion-analytics-dashboard'
  // @Decorators.TemporaryState
  isDashboardVisible: boolean = false
  charts: Map<string, EChartsTypes> = new Map()
  private currentRoleFilter: DiscussionUserRoleFilter = 'all'
  private roleChartInstances: Map<string, Map<DiscussionUserRoleFilter, ECharts>> = new Map()

  constructor(private discussionInstance: DiscussionAnalytics) {}

  /**
   * 获取单例实例
   */
  public static getInstance(discussionInstance: DiscussionAnalytics): DiscussionAnalyticsUI {
    if (!DiscussionAnalyticsUI.instance) {
      DiscussionAnalyticsUI.instance = new DiscussionAnalyticsUI(discussionInstance)
    }
    return DiscussionAnalyticsUI.instance
  }

  /**
   * 切换看板显示状态
   */
  toggleDashboard(): void {
    this.isDashboardVisible ? this.hideDashboard() : this.showDashboard()
  }

  /**
   * 显示看板
   */
  showDashboard(): void {
    const $dashboard = $(`.${this.DASHBOARD_ID}`)

    if ($dashboard.length === 0) {
      this.renderDashboard()
    }
    else {
      $dashboard.show()
    }
    this.isDashboardVisible = true
  }

  /**
   * 隐藏看板
   */
  hideDashboard(): void {
    $(`.${this.DASHBOARD_ID}`).hide()

    this.isDashboardVisible = false
  }

  /**
   * 移除看板
   */
  private removeDashboard(): void {
    $(`.${this.DASHBOARD_ID}`).remove()
  }

  /**
   * 渲染数据看板
   */
  renderDashboard(): void {
    this.clickOutsideHandler = new ClickOutsideHandler({
      condition: () => $(`.${this.DASHBOARD_ID}`).is(':visible'),
      onOutsideClick: () => this.hideDashboard(),
      excludeSelectors: [`.${this.DASHBOARD_ID}`],
    })

    if (!this.discussionInstance.analyticsData)
      return

    this.removeDashboard() // 先清理旧看板

    const $dashboard = this.createDashboard()
    this.discussionInstance.tracker.creation($dashboard)

    $('body').append($dashboard)
    ToolKit.browser.platform.markProjectAlertElement($dashboard)

    this.renderSummaryCards($dashboard)

    if (this.discussionInstance.config.showUserRankings) {
      this.renderUserRankings($dashboard)
    }

    if (this.discussionInstance.config.showTimeDistribution) {
      this.renderTimeDistribution($dashboard)
    }

    logger.info(`[${this.name}] 对话数据看板渲染完成`)
  }

  /**
   * 创建看板容器
   */
  private createDashboard(): JQuery<HTMLElement> {
    const { timeMetrics } = this.discussionInstance.analyticsData || {}
    const { firstCommentTime = 0, commentFrequency = 0 } = timeMetrics || {}

    const commentTime = ToolKit.time.formatTime(firstCommentTime)
    const frequency = commentFrequency.toFixed(1)

    return $(`
      <div class="${this.DASHBOARD_ID}">
        <div class="dashboard-header">
          <h3>${SYMBOLS.UI.CHART} 讨论看板</h3>
          <div class="dashboard-controls">
            <button class="btn-close" title="关闭看板">${SYMBOLS.UI.CLOSE}</button>
          </div>
        </div>
        <div class="dashboard-content">
          <div class="base-info">
            <div class="post-time">发帖时间：${commentTime}</div>
            <div class="comment-frequency">每天新增：${frequency} 条评论</div>
          </div> 
          <div class="summary-cards"></div>
          <div class="charts-container">
            <div class="user-ranking-section"></div>
            <div class="time-distribution-section">
              <h4>${SYMBOLS.TIME.CALENDAR} 活动时间</h4>
              <div id="activity-peak-chart"></div>
              <div id="hourly-distribution-chart"></div>
              <div id="weekly-distribution-chart"></div>
            </div>
          </div>
        </div>
      </div>
    `)
      .on('click', '.btn-close', () => this.hideDashboard())
  }

  /**
   * 渲染摘要卡片
   */
  private renderSummaryCards($dashboard: JQuery<HTMLElement>): void {
    if (!this.discussionInstance.analyticsData)
      return

    const {
      totalComments,
      uniqueParticipants,
      userRoles,
      averageCommentsPerUser,
      discussionDuration,
      timeMetrics,
      heatScore = 50,
      heatColor = '#a4b0be',
    } = this.discussionInstance.analyticsData

    const firstCommentTime = ToolKit.time.formatDateTime(timeMetrics.firstCommentTime)
    const lastCommentTime = ToolKit.time.formatDateTime(timeMetrics.lastCommentTime)
    const commentsPerUser = averageCommentsPerUser.toFixed(1)
    const averageInterval = ToolKit.time.formatTimeInterval(timeMetrics.averageInterval)

    const averageCommentsPerUserTitle = `平均每个用户发布 ${commentsPerUser} 条评论`
    const mostActiveTitle = this.getMostActiveTitle()
    const averageIntervalTitle = `平均 ${averageInterval} 新增一条评论`

    const $summaryContainer = $dashboard.find('.summary-cards')
    $summaryContainer.html(`
      <div class="summary-card overview-card">
        <!-- 热度显示区域 -->
        <div class="heat-section">
          <div class="heat-circle" style="border-color: ${heatColor}; color: ${heatColor}">
            <span class="heat-score" title="讨论热度（数值范围：${DISCUSSION_SCORE_WEIGHT_CONFIG.minScore}-${DISCUSSION_SCORE_WEIGHT_CONFIG.maxScore}）">${heatScore}</span>
          </div>
        </div>
        
        <!-- 核心指标区域 -->
        <div class="metrics-flex">
          <div class="metric-item">
            <span class="metric-icon">${SYMBOLS.OTHERS.COMMENT}</span>
            <span class="metric-value" title="评论总数">${totalComments}</span>
          </div>
          
          <div class="metric-item">
            <span class="metric-icon">${SYMBOLS.USER.ASTRONAUT}</span>
            <span class="metric-value" title="参与人数">${uniqueParticipants}</span>
          </div>
          
          <div class="metric-item">
            <span class="metric-icon">${SYMBOLS.UI.TREND_UP}</span>
            <span class="metric-value" title="${averageCommentsPerUserTitle}">${commentsPerUser}</span>
          </div>
        </div>
        
        <!-- 更新时间状态 -->
        <div class="update-status ${this.getUpdateStatusClass(timeMetrics.hoursSinceLastUpdate)}">
          （
          <span title="开始时间（${firstCommentTime}） - 结束时间（${lastCommentTime}）">讨论持续：</span>${ToolKit.time.formatTimeInterval(discussionDuration.durationHours)}，
          <span title="最近更新时间：${lastCommentTime}">距最近更新已过去：</span>${ToolKit.time.formatTimeInterval(timeMetrics.hoursSinceLastUpdate)}
          ）
        </div>
      </div>
      <div class="summary-card">
        <div class="card-icon">${SYMBOLS.USER.KING}</div>
        <div class="card-content">
          <div class="card-value">${userRoles[DiscussionUserRole.OriginalPoster]}</div>
          <div class="card-label">楼主发布</div>
        </div>
      </div>
      <div class="summary-card">
        <div class="card-icon">${SYMBOLS.USER.DEVELOPER}</div>
        <div class="card-content">
          <div class="card-value">${userRoles[DiscussionUserRole.Author]}</div>
          <div class="card-label">作者发布</div>
        </div>
      </div>
      <div class="summary-card">
        <div class="card-icon">${SYMBOLS.USER.USER_CENTER}</div>
        <div class="card-content">
          <div class="card-value" title="${mostActiveTitle}">${this.discussionInstance.analyticsData.mostActiveUser?.commentCount || 0}</div>
          <div class="card-label">最多发布</div>
        </div>
      </div>
      ${timeMetrics.averageInterval
        ? `
        <div class="summary-card">
          <div class="card-icon">${SYMBOLS.TIME.CLOCK}</div>
          <div class="card-content">
            <div class="card-value" title="${averageIntervalTitle}">${averageInterval}</div>
            <div class="card-label">回复间隔</div>
          </div>
        </div>
        <div class="summary-card" data-action="fastest-reply">
          <div class="card-icon">${SYMBOLS.ANIMAL.RABBIT}</div>
          <div class="card-content">
            <div class="card-value">${ToolKit.time.formatTimeInterval(timeMetrics.minInterval, 'minutes')}</div>
            <div class="card-label" title="点击查看评论">最快回复</div>
          </div>
        </div>
        <div class="summary-card" data-action="slowest-reply">
          <div class="card-icon">${SYMBOLS.ANIMAL.TORTOISE}</div>
          <div class="card-content">
            <div class="card-value">${ToolKit.time.formatTimeInterval(timeMetrics.maxInterval, 'minutes')}</div>
            <div class="card-label" title="点击查看评论">最慢回复</div>
          </div>
        </div>
        `
        : ''}
    `)

    // 绑定点击事件
    this.bindCardClickEvents($dashboard)
  }

  /**
   * 绑定卡片点击事件
   */
  private bindCardClickEvents($dashboard: JQuery<HTMLElement>): void {
    // 最快回复点击事件
    $dashboard.find('.summary-card[data-action="fastest-reply"]').on('click', (e) => {
      e.preventDefault()
      e.stopPropagation()

      const commentId = this.discussionInstance.analyticsData?.timeMetrics.fastestCommentId

      if (!commentId)
        return

      this.pageHandler.scrollToComment(commentId)
    })

    // 最慢回复点击事件
    $dashboard.find('.summary-card[data-action="slowest-reply"]').on('click', (e) => {
      e.preventDefault()
      e.stopPropagation()

      const commentId = this.discussionInstance.analyticsData?.timeMetrics.slowestCommentId

      if (!commentId)
        return

      this.pageHandler.scrollToComment(commentId)
    })
  }

  /**
   * 渲染用户排名
   */
  private renderUserRankings($dashboard: JQuery<HTMLElement>): void {
    if (!this.discussionInstance.analyticsData)
      return

    const $rankingSection = $dashboard.find('.user-ranking-section')
    $rankingSection.html(`
      <h4>${SYMBOLS.USER.ASTRONAUT} 用户活跃(TOP10)</h4>
      <div class="user-ranking-list">
        ${this.discussionInstance.analyticsData.userRankings.map((user, index) => `
          <div class="user-ranking-item">
            <div class="user-rank">#${index + 1}</div>
            <div class="user-avatar">
              <img src="${user.avatar}" alt="${user.name}" onerror="this.style.display='none'">
            </div>
            <div class="user-info">
              <div class="user-name">${user.name}</div>
              <div class="user-role">${this.getRoleBadge(user.role)}</div>
            </div>
            <div class="user-stats">
              <span class="comment-count">${user.commentCount} 条</span>
            </div>
          </div>
        `).join('')}
      </div>
    `)
  }

  /**
   * 渲染时间分布
   */
  private renderTimeDistribution($dashboard: JQuery<HTMLElement>): void {
    if (!this.discussionInstance.analyticsData)
      return

    // 添加角色切换
    this.renderRoleFilter($dashboard)

    // 渲染图表
    this.renderChartsByRole($dashboard, this.currentRoleFilter)
  }

  /**
   * 渲染角色切换下拉框
   */
  private renderRoleFilter($dashboard: JQuery<HTMLElement>): void {
    if (!this.discussionInstance.analyticsData)
      return

    const { roleBasedData } = this.discussionInstance.analyticsData
    const $timeSection = $dashboard.find('.time-distribution-section h4')
    this.selectInstance = new Select({
      id: 'role-filter',
      selectedValue: 'all',
      label: '',
      labelTextPosition: 'left',
      options: this.getRoleFilterOptions(roleBasedData),
      clearable: true,
      showPlaceholder: true,
      placeholder: '选择主题',
      onChange: (role: string | undefined) => {
        if (!role)
          role = 'all'

        if (role === this.currentRoleFilter)
          return // 已经是当前选中的角色

        // 更新当前筛选角色
        this.currentRoleFilter = role as DiscussionUserRole

        // 重新渲染图表
        this.renderChartsByRole($dashboard, role as DiscussionUserRole)
      },
    })

    $timeSection.after(this.selectInstance.render())
    this.selectInstance.mount($dashboard)
  }

  /**
   * 获取角色筛选下拉框选项
   */
  private getRoleFilterOptions(roleBasedData: DiscussionAnalyticsData['roleBasedData']): {
    value: DiscussionUserRoleFilter
    label: string
    disabled: boolean
  }[] {
    const roles: { value: DiscussionUserRoleFilter, label: string }[] = [
      { value: 'all', label: `${SYMBOLS.USER.ASTRONAUT} 全部` },
      { value: DiscussionUserRole.OriginalPoster, label: DiscussionUserRoleBadge.OriginalPoster },
      { value: DiscussionUserRole.Author, label: DiscussionUserRoleBadge.Author },
      { value: DiscussionUserRole.Admin, label: DiscussionUserRoleBadge.Admin },
      { value: DiscussionUserRole.RegularUser, label: DiscussionUserRoleBadge.RegularUser },
      { value: DiscussionUserRole.DeletedUser, label: DiscussionUserRoleBadge.DeletedUser },
    ]

    // 为每个角色添加评论数量
    const rolesWithCount = roles.map((role) => {
      const commentCount = role.value === 'all'
        ? this.discussionInstance.analyticsData!.totalComments
        : roleBasedData[role.value]?.commentCount || 0

      return {
        value: role.value,
        label: role.label,
        commentCount,
        disabled: commentCount === 0,
      }
    })

    // 按评论数量降序排序
    return rolesWithCount
      .sort((a, b) => b.commentCount - a.commentCount)
      .map(({ value, label, commentCount, disabled }) => ({
        value,
        label: `${label} (${commentCount})`,
        disabled,
      }))
  }

  /**
   * 渲染时间分布
   */
  private renderChartsByRole($dashboard: JQuery<HTMLElement>, role: DiscussionUserRole | 'all'): void {
    if (!this.discussionInstance.analyticsData)
      return

    const { activityPeaks, timeDistribution, roleBasedData } = this.discussionInstance.analyticsData

    // 根据角色获取数据
    let chartData: {
      activityPeaks: Array<{ hour: number, count: number }>
      timeDistribution: DiscussionTimeDistribution
    }

    if (role === 'all') {
      // 使用全部数据
      chartData = {
        activityPeaks: activityPeaks.filter(peak => peak.count > 0).slice(0, 5),
        timeDistribution,
      }
    }
    else {
      // 使用角色数据
      const roleData = roleBasedData[role]

      if (!roleData) {
        logger.warn(`[${this.name}] 未找到角色数据`, { role })
        return
      }

      chartData = {
        activityPeaks: roleData.activityPeaks.filter(peak => peak.count > 0).slice(0, 5),
        timeDistribution: roleData.timeDistribution,
      }
    }

    const CHARTS_CONFIG = [
      {
        type: 'bar',
        id: 'activity-peak-chart',
        title: '活跃时段(TOP5)',
        categories: chartData.activityPeaks.map(peak => `${peak.hour}:00-${peak.hour + 1}:00`),
        values: chartData.activityPeaks.map(peak => peak.count),
      },
      {
        type: 'line',
        id: 'hourly-distribution-chart',
        title: '24小时分布',
        // 格式化小时标签
        categories: Object.keys(chartData.timeDistribution.byHour)
          .map(hour => hour.replace(':00', '').replace(/^0+(?=\d)/, '')),
        values: Object.values(chartData.timeDistribution.byHour),
        formatTooltipName: (name: string) => `${name}:00`,
      },
      {
        type: 'bar',
        id: 'weekly-distribution-chart',
        title: '周分布',
        categories: chartData.timeDistribution.byWeekday.map((_, index) => {
          return `${WEEKDAYS_CHINESE[index]}`
        }),
        values: chartData.timeDistribution.byWeekday,
      },
    ]

    // 渲染或更新图表
    CHARTS_CONFIG.forEach((config) => {
      this.renderOrUpdateChart($dashboard, config, role)
    })
  }

  /**
   * 渲染或更新图表
   */
  private renderOrUpdateChart($dashboard: JQuery<HTMLElement>, config: any, role: DiscussionUserRole | 'all'): void {
    const { type, id, title, categories, values, formatTooltipName } = config

    // 检查图表容器是否存在
    const $chartContainer = $dashboard.find(`#${id}`)

    if ($chartContainer.length === 0) {
      logger.warn(`[${this.name}] 图表容器不存在`, { id })
      return
    }

    // 检查是否已有该图表的实例
    if (!this.roleChartInstances.has(id)) {
      this.roleChartInstances.set(id, new Map())
    }

    const chartInstances = this.roleChartInstances.get(id)!

    if (!chartInstances.has(role)) {
      // 创建新图表
      this.createNewChart($dashboard, id, type, title, categories, values, role, formatTooltipName)
    }

    // 隐藏其他角色的图表，显示当前角色的图表
    this.switchChartVisibility($dashboard, id, role)
  }

  /**
   * 创建新图表
   */
  private createNewChart(
    $dashboard: JQuery<HTMLElement>,
    id: string,
    type: string,
    title: string,
    categories: string[],
    values: number[],
    role: DiscussionUserRole | 'all',
    formatTooltipName?: (name: string) => string,
  ): void {
    let chart: any = null

    if (type === 'bar') {
      chart = new BarChart({
        id: `${id}-${role}`,
        title,
        categories,
        values,
      })
    }
    else if (type === 'line') {
      chart = new LineChart({
        id: `${id}-${role}`,
        title,
        categories,
        values,
        formatTooltipName,
      })
    }

    if (!chart)
      return

    // 创建图表容器
    const chartHtml = chart.render()
    const $chartContainer = $dashboard.find(`#${id}`)

    // 添加角色标识
    const $roleChart = $(chartHtml)
      .attr('data-role', role)
      .addClass('role-chart')
      .css('display', role === this.currentRoleFilter ? 'block' : 'none')

    $chartContainer.append($roleChart)
    chart.bindEvents()

    // 存储图表实例
    const chartInstances = this.roleChartInstances.get(id)!
    chartInstances.set(role, chart.getChartInstance())
  }

  /**
   * 切换图表可见性
   */
  private switchChartVisibility($dashboard: JQuery<HTMLElement>, chartId: string, activeRole: DiscussionUserRole | 'all'): void {
    $dashboard.find(`#${chartId} .role-chart`).hide()
    $dashboard.find(`#${chartId} .role-chart[data-role="${activeRole}"]`).show()
  }

  /**
   * 获取最活跃标题
   */
  getMostActiveTitle(): string {
    if (!this.discussionInstance.analyticsData)
      return ''

    const mostActiveName = this.discussionInstance.analyticsData.mostActiveUser?.name || '已注销'
    const mostActiveCommentCount = this.discussionInstance.analyticsData.mostActiveUser?.commentCount || 0

    if (mostActiveCommentCount === 0)
      return ''

    return `最活跃用户（${mostActiveName}） 一共发布了 ${mostActiveCommentCount} 条评论`
  }

  /**
   * 获取角色徽章
   */
  private getRoleBadge(role: DiscussionUserRole): string {
    return Object.entries(DiscussionUserRoleBadge)
      .find(([key, _]) => key === role)?.[1] || DiscussionUserRoleBadge.RegularUser
  }

  /**
   * 获取更新状态 CSS 类
   */
  private getUpdateStatusClass(hoursSinceUpdate: number): string {
    if (hoursSinceUpdate < 1)
      return 'status-fresh'
    if (hoursSinceUpdate < 24)
      return 'status-recent'
    if (hoursSinceUpdate < 168)
      return 'status-normal'
    return 'status-stale'
  }
}
